package leducHoldem.Game;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

import leducHoldem.Data.Board;
import leducHoldem.Data.Dealer;
import leducHoldem.Data.Move;
import leducHoldem.Players.Player;

public class Game {

	private static Player currentPlayer;
	private static Player firstPlayer;
	private static Player secondPlayer;
	private static Dealer dealer;

	private static Board board;

	@SuppressWarnings("unchecked")
	public static void main(String args[]) {

		Class<Player> firstPlayer_class = null;
		Class<Player> secondPlayer_class = null;

		try {
			firstPlayer_class = (Class<Player>) Class.forName(args[0]);
			secondPlayer_class = (Class<Player>) Class.forName(args[1]);
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}

		if (!Player.class.isAssignableFrom(firstPlayer_class)) {
			throw new IllegalArgumentException("Illegal player class. Must extend Player");
		}

		if (!Player.class.isAssignableFrom(secondPlayer_class)) {
			throw new IllegalArgumentException("Illegal player class. Must extend Player");
		}

		dealer = new Dealer();

		dealer.shuffle();

		Move firstCard = dealer.dealCard();
		Move secondCard = dealer.dealCard();

		Constructor<Player> firstPlayerConstructor = null;
		Constructor<Player> secondPlayerConstructor = null;

		try {
			firstPlayerConstructor = firstPlayer_class.getConstructor(new Class[] { Move.class, byte.class });
			secondPlayerConstructor = secondPlayer_class.getConstructor(new Class[] { Move.class, byte.class });
		} catch (SecurityException e) {
			e.printStackTrace();
		} catch (NoSuchMethodException e) {
			e.printStackTrace();
		}
		try {
			firstPlayer = firstPlayerConstructor.newInstance(firstCard, (byte) 1);
			secondPlayer = secondPlayerConstructor.newInstance(secondCard, (byte) 2);
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		}

		System.out.println(firstCard);
		System.out.println(secondCard);

		board = new Board(firstCard, secondCard);

		currentPlayer = firstPlayer;

		new Game().runGame(firstPlayer, secondPlayer);

	}

	private void runGame(Player firstPlayer, Player secondPlayer) {

		Move move;
		int value = 0;

		while (board.isTerminal() == 0) {

			System.out.println();
			System.out.println("Table: " + board.table);
			System.out.println("Pot: " + board.getPot());
			System.out.println("Opponent's action: " + board.getLastMove());
			System.out.println("Current player: " + board.currentPlayer);
			System.out.println("Id: " + board.id);
			System.out.println();

			do {
				move = currentPlayer.getNextNode(new Board(board), true);
			} while (!board.isValid(move));

			value = board.makeMove(move);

			if (value == 2) {
				board.makeMove(dealer.dealCard());
			}

			switchPlayers(value);
		}

		System.out.println();
		System.out.println("Board id: " + board.id);
		System.out.println("Table: " + board.table);
		System.out.println("Pot: " + board.getPot());
		System.out.println("Opponent's action: " + board.getLastMove());
		System.out.println();

		System.out.println("Player " + board.isTerminal() + " won.");

	}

	private void switchPlayers(int value) {

		if (value == 2) {
			currentPlayer = firstPlayer;
			return;
		}

		if (currentPlayer.sign == 1) {
			currentPlayer = secondPlayer;
			return;
		}

		currentPlayer = firstPlayer;

	}
}
